<?php


namespace Melon;


use EventBase;
use EventHttp;
use EventHttpRequest;
use Throwable;

class Worker
{
    /**
     * @var Application
     */
    protected Application $app;

    /**
     * @var EventBase
     */
    protected EventBase $base;

    protected EventHttp $http;

    /**
     * @var resource
     */
    protected $socket;

    public function __construct(Application $app)
    {
        $this->app = $app;

        $this->base = new EventBase();

        $this->http = new EventHttp($this->base);
    }

    public function run()
    {
        $this->init();

        $this->base->loop();
    }

    protected function init()
    {
        // set allow request method
        $this->http->setAllowedMethods(EventHttpRequest::CMD_GET | EventHttpRequest::CMD_POST);

        $this->http->setDefaultCallback(function (EventHttpRequest $req) {
            try {
                $connection = new Connection($req, $this, $this->app);

                $connection->handle();
            } catch (Throwable $e) {
                $response = new Response($req);
                $response->setCode(500);
                $response->setContent("Error " . $e->getCode() . ": " . $e->getMessage());
                $response->send();
            }
        }, 'default');

        $this->socket = stream_socket_server($this->app->getAddress());
        stream_context_set_option($this->socket, 'socket', 'so_reuseport', 1); // set reusePort

        $this->http->accept($this->socket);
    }
}
